<html>
    <head>
       <style type="text/css">
            .hll { background-color: #ffffcc }
.c { color: #888888 } /* Comment */
.err { color: #a61717; background-color: #e3d2d2 } /* Error */
.k { color: #008800; font-weight: bold } /* Keyword */
.cm { color: #888888 } /* Comment.Multiline */
.cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */
.c1 { color: #888888 } /* Comment.Single */
.cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */
.gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.ge { font-style: italic } /* Generic.Emph */
.gr { color: #aa0000 } /* Generic.Error */
.gh { color: #333333 } /* Generic.Heading */
.gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.go { color: #888888 } /* Generic.Output */
.gp { color: #555555 } /* Generic.Prompt */
.gs { font-weight: bold } /* Generic.Strong */
.gu { color: #666666 } /* Generic.Subheading */
.gt { color: #aa0000 } /* Generic.Traceback */
.kc { color: #008800; font-weight: bold } /* Keyword.Constant */
.kd { color: #008800; font-weight: bold } /* Keyword.Declaration */
.kn { color: #008800; font-weight: bold } /* Keyword.Namespace */
.kp { color: #008800 } /* Keyword.Pseudo */
.kr { color: #008800; font-weight: bold } /* Keyword.Reserved */
.kt { color: #888888; font-weight: bold } /* Keyword.Type */
.m { color: #0000DD; font-weight: bold } /* Literal.Number */
.s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */
.na { color: #336699 } /* Name.Attribute */
.nb { color: #003388 } /* Name.Builtin */
.nc { color: #bb0066; font-weight: bold } /* Name.Class */
.no { color: #003366; font-weight: bold } /* Name.Constant */
.nd { color: #555555 } /* Name.Decorator */
.ne { color: #bb0066; font-weight: bold } /* Name.Exception */
.nf { color: #0066bb; font-weight: bold } /* Name.Function */
.nl { color: #336699; font-style: italic } /* Name.Label */
.nn { color: #bb0066; font-weight: bold } /* Name.Namespace */
.py { color: #336699; font-weight: bold } /* Name.Property */
.nt { color: #bb0066; font-weight: bold } /* Name.Tag */
.nv { color: #336699 } /* Name.Variable */
.ow { color: #008800 } /* Operator.Word */
.w { color: #bbbbbb } /* Text.Whitespace */
.mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */
.mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */
.mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */
.mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */
.sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */
.sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */
.sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */
.s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */
.se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */
.sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */
.si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */
.sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */
.sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */
.s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */
.ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */
.bp { color: #003388 } /* Name.Builtin.Pseudo */
.vc { color: #336699 } /* Name.Variable.Class */
.vg { color: #dd7700 } /* Name.Variable.Global */
.vi { color: #3333bb } /* Name.Variable.Instance */
.il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
        </style>
    </head>
    <body>

<h1>MQTT 3.1.1 packet formats</h1>
<pre>
<div class="highlight"><pre><a name="MQTTV311.py-pyg.html-1"></a><span class="sd">&quot;&quot;&quot;</span>
<a name="MQTTV311.py-pyg.html-2"></a><span class="sd">*******************************************************************</span>
<a name="MQTTV311.py-pyg.html-3"></a><span class="sd">  Copyright (c) 2013, 2014 IBM Corp.</span>
<a name="MQTTV311.py-pyg.html-4"></a><span class="sd"> </span>
<a name="MQTTV311.py-pyg.html-5"></a><span class="sd">  All rights reserved. This program and the accompanying materials</span>
<a name="MQTTV311.py-pyg.html-6"></a><span class="sd">  are made available under the terms of the Eclipse Public License v1.0</span>
<a name="MQTTV311.py-pyg.html-7"></a><span class="sd">  and Eclipse Distribution License v1.0 which accompany this distribution. </span>
<a name="MQTTV311.py-pyg.html-8"></a><span class="sd"> </span>
<a name="MQTTV311.py-pyg.html-9"></a><span class="sd">  The Eclipse Public License is available at </span>
<a name="MQTTV311.py-pyg.html-10"></a><span class="sd">     http://www.eclipse.org/legal/epl-v10.html</span>
<a name="MQTTV311.py-pyg.html-11"></a><span class="sd">  and the Eclipse Distribution License is available at </span>
<a name="MQTTV311.py-pyg.html-12"></a><span class="sd">    http://www.eclipse.org/org/documents/edl-v10.php.</span>
<a name="MQTTV311.py-pyg.html-13"></a><span class="sd"> </span>
<a name="MQTTV311.py-pyg.html-14"></a><span class="sd">  Contributors:</span>
<a name="MQTTV311.py-pyg.html-15"></a><span class="sd">     Ian Craggs - initial implementation and/or documentation</span>
<a name="MQTTV311.py-pyg.html-16"></a><span class="sd">*******************************************************************</span>
<a name="MQTTV311.py-pyg.html-17"></a>
<a name="MQTTV311.py-pyg.html-18"></a>
<a name="MQTTV311.py-pyg.html-19"></a><span class="sd">Assertions are used to validate incoming data, but are omitted from outgoing packets.  This is</span>
<a name="MQTTV311.py-pyg.html-20"></a><span class="sd">so that the tests that use this package can send invalid data for error testing.</span>
<a name="MQTTV311.py-pyg.html-21"></a>
<a name="MQTTV311.py-pyg.html-22"></a><span class="sd">&quot;&quot;&quot;</span>
<a name="MQTTV311.py-pyg.html-23"></a>
<a name="MQTTV311.py-pyg.html-24"></a><span class="kn">import</span> <span class="nn">logging</span>
<a name="MQTTV311.py-pyg.html-25"></a>
<a name="MQTTV311.py-pyg.html-26"></a><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="s">&#39;MQTT broker&#39;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-27"></a>
<a name="MQTTV311.py-pyg.html-28"></a><span class="c"># Low-level protocol interface</span>
<a name="MQTTV311.py-pyg.html-29"></a>
<a name="MQTTV311.py-pyg.html-30"></a><span class="k">class</span> <span class="nc">MQTTException</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-31"></a>  <span class="k">pass</span>
<a name="MQTTV311.py-pyg.html-32"></a>   
<a name="MQTTV311.py-pyg.html-33"></a>
<a name="MQTTV311.py-pyg.html-34"></a><span class="c"># Message types</span>
<a name="MQTTV311.py-pyg.html-35"></a><span class="n">CONNECT</span><span class="p">,</span> <span class="n">CONNACK</span><span class="p">,</span> <span class="n">PUBLISH</span><span class="p">,</span> <span class="n">PUBACK</span><span class="p">,</span> <span class="n">PUBREC</span><span class="p">,</span> <span class="n">PUBREL</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-36"></a><span class="n">PUBCOMP</span><span class="p">,</span> <span class="n">SUBSCRIBE</span><span class="p">,</span> <span class="n">SUBACK</span><span class="p">,</span> <span class="n">UNSUBSCRIBE</span><span class="p">,</span> <span class="n">UNSUBACK</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-37"></a><span class="n">PINGREQ</span><span class="p">,</span> <span class="n">PINGRESP</span><span class="p">,</span> <span class="n">DISCONNECT</span> <span class="o">=</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">15</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-38"></a>
<a name="MQTTV311.py-pyg.html-39"></a><span class="n">packetNames</span> <span class="o">=</span> <span class="p">[</span> <span class="s">&quot;reserved&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-40"></a><span class="s">&quot;Connect&quot;</span><span class="p">,</span> <span class="s">&quot;Connack&quot;</span><span class="p">,</span> <span class="s">&quot;Publish&quot;</span><span class="p">,</span> <span class="s">&quot;Puback&quot;</span><span class="p">,</span> <span class="s">&quot;Pubrec&quot;</span><span class="p">,</span> <span class="s">&quot;Pubrel&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-41"></a><span class="s">&quot;Pubcomp&quot;</span><span class="p">,</span> <span class="s">&quot;Subscribe&quot;</span><span class="p">,</span> <span class="s">&quot;Suback&quot;</span><span class="p">,</span> <span class="s">&quot;Unsubscribe&quot;</span><span class="p">,</span> <span class="s">&quot;Unsuback&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-42"></a><span class="s">&quot;Pingreq&quot;</span><span class="p">,</span> <span class="s">&quot;Pingresp&quot;</span><span class="p">,</span> <span class="s">&quot;Disconnect&quot;</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-43"></a>
<a name="MQTTV311.py-pyg.html-44"></a><span class="n">classNames</span> <span class="o">=</span> <span class="p">[</span> <span class="s">&quot;reserved&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-45"></a><span class="s">&quot;Connects&quot;</span><span class="p">,</span> <span class="s">&quot;Connacks&quot;</span><span class="p">,</span> <span class="s">&quot;Publishes&quot;</span><span class="p">,</span> <span class="s">&quot;Pubacks&quot;</span><span class="p">,</span> <span class="s">&quot;Pubrecs&quot;</span><span class="p">,</span> <span class="s">&quot;Pubrels&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-46"></a><span class="s">&quot;Pubcomps&quot;</span><span class="p">,</span> <span class="s">&quot;Subscribes&quot;</span><span class="p">,</span> <span class="s">&quot;Subacks&quot;</span><span class="p">,</span> <span class="s">&quot;Unsubscribes&quot;</span><span class="p">,</span> <span class="s">&quot;Unsubacks&quot;</span><span class="p">,</span> \
<a name="MQTTV311.py-pyg.html-47"></a><span class="s">&quot;Pingreqs&quot;</span><span class="p">,</span> <span class="s">&quot;Pingresps&quot;</span><span class="p">,</span> <span class="s">&quot;Disconnects&quot;</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-48"></a>
<a name="MQTTV311.py-pyg.html-49"></a>
<a name="MQTTV311.py-pyg.html-50"></a><span class="k">def</span> <span class="nf">MessageType</span><span class="p">(</span><span class="n">byte</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-51"></a>  <span class="k">if</span> <span class="n">byte</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-52"></a>    <span class="n">rc</span> <span class="o">=</span> <span class="n">byte</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;&gt;</span> <span class="mi">4</span>
<a name="MQTTV311.py-pyg.html-53"></a>  <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-54"></a>    <span class="n">rc</span> <span class="o">=</span> <span class="bp">None</span>
<a name="MQTTV311.py-pyg.html-55"></a>  <span class="k">return</span> <span class="n">rc</span>
<a name="MQTTV311.py-pyg.html-56"></a>
<a name="MQTTV311.py-pyg.html-57"></a>
<a name="MQTTV311.py-pyg.html-58"></a><span class="k">def</span> <span class="nf">getPacket</span><span class="p">(</span><span class="n">aSocket</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-59"></a>  <span class="s">&quot;receive the next packet&quot;</span>
<a name="MQTTV311.py-pyg.html-60"></a>  <span class="n">buf</span> <span class="o">=</span> <span class="n">aSocket</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c"># get the first byte fixed header</span>
<a name="MQTTV311.py-pyg.html-61"></a>  <span class="k">if</span> <span class="n">buf</span> <span class="o">==</span> <span class="n">b</span><span class="s">&quot;&quot;</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-62"></a>    <span class="k">return</span> <span class="bp">None</span>
<a name="MQTTV311.py-pyg.html-63"></a>  <span class="c"># now get the remaining length</span>
<a name="MQTTV311.py-pyg.html-64"></a>  <span class="n">multiplier</span> <span class="o">=</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-65"></a>  <span class="n">remlength</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-66"></a>  <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-67"></a>    <span class="n">buf</span> <span class="o">+=</span> <span class="n">aSocket</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-68"></a>    <span class="n">digit</span> <span class="o">=</span> <span class="n">buf</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-69"></a>    <span class="n">remlength</span> <span class="o">+=</span> <span class="p">(</span><span class="n">digit</span> <span class="o">&amp;</span> <span class="mi">127</span><span class="p">)</span> <span class="o">*</span> <span class="n">multiplier</span>
<a name="MQTTV311.py-pyg.html-70"></a>    <span class="k">if</span> <span class="n">digit</span> <span class="o">&amp;</span> <span class="mi">128</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-71"></a>      <span class="k">break</span>
<a name="MQTTV311.py-pyg.html-72"></a>    <span class="n">multiplier</span> <span class="o">*=</span> <span class="mi">128</span>
<a name="MQTTV311.py-pyg.html-73"></a>  <span class="c"># receive the remaining length if there is any</span>
<a name="MQTTV311.py-pyg.html-74"></a>  <span class="n">rest</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([])</span>
<a name="MQTTV311.py-pyg.html-75"></a>  <span class="k">if</span> <span class="n">remlength</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-76"></a>    <span class="k">while</span> <span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">remlength</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-77"></a>      <span class="n">rest</span> <span class="o">+=</span> <span class="n">aSocket</span><span class="o">.</span><span class="n">recv</span><span class="p">(</span><span class="n">remlength</span><span class="o">-</span><span class="nb">len</span><span class="p">(</span><span class="n">rest</span><span class="p">))</span>
<a name="MQTTV311.py-pyg.html-78"></a>  <span class="k">return</span> <span class="n">buf</span> <span class="o">+</span> <span class="n">rest</span>
<a name="MQTTV311.py-pyg.html-79"></a>
<a name="MQTTV311.py-pyg.html-80"></a>
<a name="MQTTV311.py-pyg.html-81"></a><span class="k">class</span> <span class="nc">FixedHeaders</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-82"></a>
<a name="MQTTV311.py-pyg.html-83"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">aMessageType</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-84"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">MessageType</span> <span class="o">=</span> <span class="n">aMessageType</span>
<a name="MQTTV311.py-pyg.html-85"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-86"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-87"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">=</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-88"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-89"></a>
<a name="MQTTV311.py-pyg.html-90"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">fh</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-91"></a>    <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">MessageType</span> <span class="o">==</span> <span class="n">fh</span><span class="o">.</span><span class="n">MessageType</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-92"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-93"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-94"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="c"># and \</span>
<a name="MQTTV311.py-pyg.html-95"></a>           <span class="c"># self.remainingLength == fh.remainingLength</span>
<a name="MQTTV311.py-pyg.html-96"></a>
<a name="MQTTV311.py-pyg.html-97"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-98"></a>    <span class="s">&quot;return printable representation of our data&quot;</span>
<a name="MQTTV311.py-pyg.html-99"></a>    <span class="k">return</span> <span class="n">classNames</span><span class="p">[</span><span class="bp">self</span><span class="o">.</span><span class="n">MessageType</span><span class="p">]</span><span class="o">+</span><span class="s">&#39;(DUP=&#39;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">DUP</span><span class="p">)</span><span class="o">+</span> \
<a name="MQTTV311.py-pyg.html-100"></a>           <span class="s">&quot;, QoS=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">QoS</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, Retain=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">RETAIN</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-101"></a>
<a name="MQTTV311.py-pyg.html-102"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">length</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-103"></a>    <span class="s">&quot;pack data into string buffer ready for transmission down socket&quot;</span>
<a name="MQTTV311.py-pyg.html-104"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([(</span><span class="bp">self</span><span class="o">.</span><span class="n">MessageType</span> <span class="o">&lt;&lt;</span> <span class="mi">4</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">DUP</span> <span class="o">&lt;&lt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">|</span>\
<a name="MQTTV311.py-pyg.html-105"></a>                         <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">QoS</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">|</span> <span class="bp">self</span><span class="o">.</span><span class="n">RETAIN</span><span class="p">])</span>
<a name="MQTTV311.py-pyg.html-106"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">=</span> <span class="n">length</span>
<a name="MQTTV311.py-pyg.html-107"></a>    <span class="nb">buffer</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="n">length</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-108"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-109"></a>
<a name="MQTTV311.py-pyg.html-110"></a>  <span class="k">def</span> <span class="nf">encode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">x</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-111"></a>    <span class="k">assert</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">x</span> <span class="o">&lt;=</span> <span class="mi">268435455</span>
<a name="MQTTV311.py-pyg.html-112"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">b</span><span class="s">&#39;&#39;</span>
<a name="MQTTV311.py-pyg.html-113"></a>    <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-114"></a>      <span class="n">digit</span> <span class="o">=</span> <span class="n">x</span> <span class="o">%</span> <span class="mi">128</span>
<a name="MQTTV311.py-pyg.html-115"></a>      <span class="n">x</span> <span class="o">//=</span> <span class="mi">128</span>
<a name="MQTTV311.py-pyg.html-116"></a>      <span class="k">if</span> <span class="n">x</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-117"></a>        <span class="n">digit</span> <span class="o">|=</span> <span class="mh">0x80</span>
<a name="MQTTV311.py-pyg.html-118"></a>      <span class="nb">buffer</span> <span class="o">+=</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">digit</span><span class="p">])</span>
<a name="MQTTV311.py-pyg.html-119"></a>      <span class="k">if</span> <span class="n">x</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-120"></a>        <span class="k">break</span>
<a name="MQTTV311.py-pyg.html-121"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-122"></a>
<a name="MQTTV311.py-pyg.html-123"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-124"></a>    <span class="s">&quot;unpack data from string buffer into separate fields&quot;</span>
<a name="MQTTV311.py-pyg.html-125"></a>    <span class="n">b0</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-126"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">MessageType</span> <span class="o">=</span> <span class="n">b0</span> <span class="o">&gt;&gt;</span> <span class="mi">4</span>
<a name="MQTTV311.py-pyg.html-127"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="p">((</span><span class="n">b0</span> <span class="o">&gt;&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-128"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="p">(</span><span class="n">b0</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x03</span>
<a name="MQTTV311.py-pyg.html-129"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">=</span> <span class="p">(</span><span class="n">b0</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-130"></a>    <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">remainingLength</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">)</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="mi">1</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-131"></a>    <span class="k">return</span> <span class="nb">bytes</span> <span class="o">+</span> <span class="mi">1</span> <span class="c"># length of fixed header</span>
<a name="MQTTV311.py-pyg.html-132"></a>
<a name="MQTTV311.py-pyg.html-133"></a>  <span class="k">def</span> <span class="nf">decode</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-134"></a>    <span class="n">multiplier</span> <span class="o">=</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-135"></a>    <span class="n">value</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-136"></a>    <span class="nb">bytes</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-137"></a>    <span class="k">while</span> <span class="mi">1</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-138"></a>      <span class="nb">bytes</span> <span class="o">+=</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-139"></a>      <span class="n">digit</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-140"></a>      <span class="nb">buffer</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>
<a name="MQTTV311.py-pyg.html-141"></a>      <span class="n">value</span> <span class="o">+=</span> <span class="p">(</span><span class="n">digit</span> <span class="o">&amp;</span> <span class="mi">127</span><span class="p">)</span> <span class="o">*</span> <span class="n">multiplier</span>
<a name="MQTTV311.py-pyg.html-142"></a>      <span class="k">if</span> <span class="n">digit</span> <span class="o">&amp;</span> <span class="mi">128</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-143"></a>        <span class="k">break</span>
<a name="MQTTV311.py-pyg.html-144"></a>      <span class="n">multiplier</span> <span class="o">*=</span> <span class="mi">128</span>
<a name="MQTTV311.py-pyg.html-145"></a>    <span class="k">return</span> <span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="nb">bytes</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-146"></a>
<a name="MQTTV311.py-pyg.html-147"></a>
<a name="MQTTV311.py-pyg.html-148"></a><span class="k">def</span> <span class="nf">writeInt16</span><span class="p">(</span><span class="n">length</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-149"></a>  <span class="k">return</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">length</span> <span class="o">//</span> <span class="mi">256</span><span class="p">,</span> <span class="n">length</span> <span class="o">%</span> <span class="mi">256</span><span class="p">])</span>
<a name="MQTTV311.py-pyg.html-150"></a>
<a name="MQTTV311.py-pyg.html-151"></a><span class="k">def</span> <span class="nf">readInt16</span><span class="p">(</span><span class="n">buf</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-152"></a>  <span class="k">return</span> <span class="n">buf</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">*</span><span class="mi">256</span> <span class="o">+</span> <span class="n">buf</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-153"></a>
<a name="MQTTV311.py-pyg.html-154"></a><span class="k">def</span> <span class="nf">writeUTF</span><span class="p">(</span><span class="n">data</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-155"></a>  <span class="c"># data could be a string, or bytes.  If string, encode into bytes with utf-8</span>
<a name="MQTTV311.py-pyg.html-156"></a>  <span class="k">return</span> <span class="n">writeInt16</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">data</span><span class="p">))</span> <span class="o">+</span> <span class="p">(</span><span class="n">data</span> <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="o">==</span> <span class="nb">type</span><span class="p">(</span><span class="n">b</span><span class="s">&quot;&quot;</span><span class="p">)</span> <span class="k">else</span> <span class="nb">bytes</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="s">&quot;utf-8&quot;</span><span class="p">))</span>
<a name="MQTTV311.py-pyg.html-157"></a>
<a name="MQTTV311.py-pyg.html-158"></a><span class="k">def</span> <span class="nf">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">,</span> <span class="n">maxlen</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-159"></a>  <span class="k">if</span> <span class="n">maxlen</span> <span class="o">&gt;</span> <span class="mi">2</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-160"></a>    <span class="n">length</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-161"></a>  <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-162"></a>    <span class="k">raise</span> <span class="n">MQTTException</span><span class="p">(</span><span class="s">&quot;Not enough data to read string length&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-163"></a>  <span class="n">maxlen</span> <span class="o">-=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-164"></a>  <span class="k">if</span> <span class="n">length</span> <span class="o">&gt;</span> <span class="n">maxlen</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-165"></a>    <span class="k">raise</span> <span class="n">MQTTException</span><span class="p">(</span><span class="s">&quot;Length delimited string too long&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-166"></a>  <span class="n">buf</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">2</span><span class="o">+</span><span class="n">length</span><span class="p">]</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s">&quot;utf-8&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-167"></a>  <span class="n">zz</span> <span class="o">=</span> <span class="n">buf</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\x00</span><span class="s">&quot;</span><span class="p">)</span> <span class="c"># look for null in the UTF string</span>
<a name="MQTTV311.py-pyg.html-168"></a>  <span class="k">if</span> <span class="n">zz</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-169"></a>    <span class="k">raise</span> <span class="n">MQTTException</span><span class="p">(</span><span class="s">&quot;[MQTT-1.4.0-2] Null found in UTF data &quot;</span><span class="o">+</span><span class="n">buf</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-170"></a>  <span class="k">if</span> <span class="n">buf</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s">&quot;</span><span class="se">\uFEFF</span><span class="s">&quot;</span><span class="p">)</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-171"></a>    <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-1.2.0-3] U+FEFF in UTF string&quot;</span><span class="p">)</span> 
<a name="MQTTV311.py-pyg.html-172"></a>  <span class="k">return</span> <span class="n">buf</span>
<a name="MQTTV311.py-pyg.html-173"></a>
<a name="MQTTV311.py-pyg.html-174"></a><span class="k">def</span> <span class="nf">writeBytes</span><span class="p">(</span><span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-175"></a>  <span class="k">return</span> <span class="n">writeInt16</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-176"></a>
<a name="MQTTV311.py-pyg.html-177"></a><span class="k">def</span> <span class="nf">readBytes</span><span class="p">(</span><span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-178"></a>  <span class="n">length</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-179"></a>  <span class="k">return</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">2</span><span class="p">:</span><span class="mi">2</span><span class="o">+</span><span class="n">length</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-180"></a>
<a name="MQTTV311.py-pyg.html-181"></a>
<a name="MQTTV311.py-pyg.html-182"></a><span class="k">class</span> <span class="nc">Packets</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-183"></a>
<a name="MQTTV311.py-pyg.html-184"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-185"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-186"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-187"></a>
<a name="MQTTV311.py-pyg.html-188"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-189"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-190"></a>
<a name="MQTTV311.py-pyg.html-191"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-192"></a>    <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">fh</span> <span class="k">if</span> <span class="n">packet</span> <span class="k">else</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-193"></a>
<a name="MQTTV311.py-pyg.html-194"></a>
<a name="MQTTV311.py-pyg.html-195"></a><span class="k">class</span> <span class="nc">Connects</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-196"></a>
<a name="MQTTV311.py-pyg.html-197"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">None</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-198"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">CONNECT</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-199"></a>
<a name="MQTTV311.py-pyg.html-200"></a>    <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-201"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span> <span class="o">=</span> <span class="s">&quot;MQTT&quot;</span>
<a name="MQTTV311.py-pyg.html-202"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span> <span class="o">=</span> <span class="mi">4</span>
<a name="MQTTV311.py-pyg.html-203"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">CleanSession</span> <span class="o">=</span> <span class="bp">True</span>
<a name="MQTTV311.py-pyg.html-204"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="o">=</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-205"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-206"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-207"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">KeepAliveTimer</span> <span class="o">=</span> <span class="mi">30</span>
<a name="MQTTV311.py-pyg.html-208"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span> <span class="o">=</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-209"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span> <span class="o">=</span> <span class="bp">False</span>
<a name="MQTTV311.py-pyg.html-210"></a>
<a name="MQTTV311.py-pyg.html-211"></a>    <span class="c"># Payload</span>
<a name="MQTTV311.py-pyg.html-212"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span> <span class="o">=</span> <span class="s">&quot;&quot;</span>   <span class="c"># UTF-8</span>
<a name="MQTTV311.py-pyg.html-213"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span> <span class="o">=</span> <span class="bp">None</span>        <span class="c"># UTF-8</span>
<a name="MQTTV311.py-pyg.html-214"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span> <span class="o">=</span> <span class="bp">None</span>      <span class="c"># binary</span>
<a name="MQTTV311.py-pyg.html-215"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="bp">None</span>         <span class="c"># UTF-8</span>
<a name="MQTTV311.py-pyg.html-216"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="bp">None</span>         <span class="c"># binary</span>
<a name="MQTTV311.py-pyg.html-217"></a>
<a name="MQTTV311.py-pyg.html-218"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-219"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-220"></a>
<a name="MQTTV311.py-pyg.html-221"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>    
<a name="MQTTV311.py-pyg.html-222"></a>    <span class="n">connectFlags</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([(</span><span class="bp">self</span><span class="o">.</span><span class="n">CleanSession</span> <span class="o">&lt;&lt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="o">&lt;&lt;</span> <span class="mi">2</span><span class="p">)</span> <span class="o">|</span> \
<a name="MQTTV311.py-pyg.html-223"></a>                       <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="o">&lt;&lt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="o">&lt;&lt;</span> <span class="mi">5</span><span class="p">)</span> <span class="o">|</span> \
<a name="MQTTV311.py-pyg.html-224"></a>                       <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span> <span class="o">&lt;&lt;</span> <span class="mi">6</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span> <span class="o">&lt;&lt;</span> <span class="mi">7</span><span class="p">)])</span>
<a name="MQTTV311.py-pyg.html-225"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span><span class="p">)</span> <span class="o">+</span> <span class="nb">bytes</span><span class="p">([</span><span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span><span class="p">])</span> <span class="o">+</span> \
<a name="MQTTV311.py-pyg.html-226"></a>              <span class="n">connectFlags</span> <span class="o">+</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">KeepAliveTimer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-227"></a>    <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span><span class="p">)</span> 
<a name="MQTTV311.py-pyg.html-228"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-229"></a>      <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span><span class="p">)</span> 
<a name="MQTTV311.py-pyg.html-230"></a>      <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeBytes</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span><span class="p">)</span> 
<a name="MQTTV311.py-pyg.html-231"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-232"></a>      <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">)</span> 
<a name="MQTTV311.py-pyg.html-233"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-234"></a>      <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeBytes</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> 
<a name="MQTTV311.py-pyg.html-235"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-236"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-237"></a>
<a name="MQTTV311.py-pyg.html-238"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-239"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-240"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">CONNECT</span>
<a name="MQTTV311.py-pyg.html-241"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-242"></a>    <span class="n">packlen</span> <span class="o">=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-243"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">packlen</span>
<a name="MQTTV311.py-pyg.html-244"></a>    <span class="n">curlen</span> <span class="o">=</span> <span class="n">fhlen</span> <span class="c"># points to after header + remaining length</span>
<a name="MQTTV311.py-pyg.html-245"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-246"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-247"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-248"></a>
<a name="MQTTV311.py-pyg.html-249"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:],</span> <span class="n">packlen</span> <span class="o">-</span> <span class="n">curlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-250"></a>    <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-251"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span> <span class="o">==</span> <span class="s">&quot;MQTT&quot;</span><span class="p">,</span> <span class="s">&quot;Wrong protocol name </span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span>
<a name="MQTTV311.py-pyg.html-252"></a>
<a name="MQTTV311.py-pyg.html-253"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-254"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">4</span><span class="p">],</span> <span class="s">&quot;Wrong protocol version </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span>
<a name="MQTTV311.py-pyg.html-255"></a>    <span class="n">curlen</span> <span class="o">+=</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-256"></a>    
<a name="MQTTV311.py-pyg.html-257"></a>    <span class="n">connectFlags</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-258"></a>    <span class="k">assert</span> <span class="p">(</span><span class="n">connectFlags</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-3.1.2-3] reserved connect flag must be 0&quot;</span>
<a name="MQTTV311.py-pyg.html-259"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">CleanSession</span> <span class="o">=</span> <span class="p">((</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-260"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="o">=</span> <span class="p">((</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">2</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-261"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="o">=</span> <span class="p">(</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">3</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x03</span>
<a name="MQTTV311.py-pyg.html-262"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="o">=</span> <span class="p">(</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">5</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span>
<a name="MQTTV311.py-pyg.html-263"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span> <span class="o">=</span> <span class="p">((</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">6</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-264"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span> <span class="o">=</span> <span class="p">((</span><span class="n">connectFlags</span> <span class="o">&gt;&gt;</span> <span class="mi">7</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x01</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-265"></a>    <span class="n">curlen</span> <span class="o">+=</span><span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-266"></a>
<a name="MQTTV311.py-pyg.html-267"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-268"></a>      <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="s">&quot;[MQTT-3.1.2-12] will qos must not be 3&quot;</span>
<a name="MQTTV311.py-pyg.html-269"></a>    <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-270"></a>      <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-3.1.2-11] will qos must be 0, if will flag is false&quot;</span>
<a name="MQTTV311.py-pyg.html-271"></a>      <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-3.1.2-13] will retain must be false, if will flag is false&quot;</span>
<a name="MQTTV311.py-pyg.html-272"></a>
<a name="MQTTV311.py-pyg.html-273"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">KeepAliveTimer</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-274"></a>    <span class="n">curlen</span> <span class="o">+=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-275"></a>    <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.3-3] Clientid must be present, and first field&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-276"></a>    <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.3-4] Clientid must be Unicode, and between 0 and 65535 bytes long&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-277"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:],</span> <span class="n">packlen</span> <span class="o">-</span> <span class="n">curlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-278"></a>    <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-279"></a>
<a name="MQTTV311.py-pyg.html-280"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-281"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:],</span> <span class="n">packlen</span> <span class="o">-</span> <span class="n">curlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-282"></a>      <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-283"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span> <span class="o">=</span> <span class="n">readBytes</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-284"></a>      <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-285"></a>      <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[[MQTT-3.1.2-9] will topic and will message fields must be present&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-286"></a>    <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-287"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span> <span class="o">=</span> <span class="bp">None</span>
<a name="MQTTV311.py-pyg.html-288"></a>
<a name="MQTTV311.py-pyg.html-289"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-290"></a>      <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">curlen</span><span class="o">+</span><span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Buffer too short to read username length&quot;</span>
<a name="MQTTV311.py-pyg.html-291"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">username</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:],</span> <span class="n">packlen</span> <span class="o">-</span> <span class="n">curlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-292"></a>      <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-293"></a>      <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.2-17] username must be in payload if user name flag is 1&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-294"></a>    <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-295"></a>      <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.2-16] username must not be in payload if user name flag is 0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-296"></a>      <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-3.1.2-20] password flag must be 0 if username flag is 0&quot;</span>
<a name="MQTTV311.py-pyg.html-297"></a>
<a name="MQTTV311.py-pyg.html-298"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-299"></a>      <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;</span> <span class="n">curlen</span><span class="o">+</span><span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Buffer too short to read password length&quot;</span>
<a name="MQTTV311.py-pyg.html-300"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">password</span> <span class="o">=</span> <span class="n">readBytes</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-301"></a>      <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-302"></a>      <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.2-19] password must be in payload if password flag is 0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-303"></a>    <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-304"></a>      <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.2-16] username must not be in payload if user name flag is 0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-305"></a>
<a name="MQTTV311.py-pyg.html-306"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-307"></a>      <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.1.3-1] clientid, will topic, will message, username and password all present&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-308"></a>
<a name="MQTTV311.py-pyg.html-309"></a>    <span class="k">assert</span> <span class="n">curlen</span> <span class="o">==</span> <span class="n">packlen</span><span class="p">,</span> <span class="s">&quot;Packet is wrong length curlen </span><span class="si">%d</span><span class="s"> != packlen </span><span class="si">%d</span><span class="s">&quot;</span>
<a name="MQTTV311.py-pyg.html-310"></a>
<a name="MQTTV311.py-pyg.html-311"></a>
<a name="MQTTV311.py-pyg.html-312"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-313"></a>    <span class="n">buf</span> <span class="o">=</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, ProtocolName=&quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, ProtocolVersion=&quot;</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-314"></a>          <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, CleanSession=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">CleanSession</span><span class="p">)</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-315"></a>          <span class="s">&quot;, WillFlag=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, KeepAliveTimer=&quot;</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-316"></a>          <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">KeepAliveTimer</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, ClientId=&quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span><span class="p">)</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-317"></a>          <span class="s">&quot;, usernameFlag=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">usernameFlag</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, passwordFlag=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">passwordFlag</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-318"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-319"></a>      <span class="n">buf</span> <span class="o">+=</span> <span class="s">&quot;, WillQoS=&quot;</span> <span class="o">+</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span><span class="p">)</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-320"></a>             <span class="s">&quot;, WillRETAIN=&quot;</span> <span class="o">+</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span><span class="p">)</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-321"></a>             <span class="s">&quot;, WillTopic=&#39;&quot;</span><span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span> <span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-322"></a>             <span class="s">&quot;&#39;, WillMessage=&#39;&quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;&#39;&quot;</span>
<a name="MQTTV311.py-pyg.html-323"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">username</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-324"></a>      <span class="n">buf</span> <span class="o">+=</span> <span class="s">&quot;, username=&quot;</span><span class="o">+</span><span class="bp">self</span><span class="o">.</span><span class="n">username</span>
<a name="MQTTV311.py-pyg.html-325"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-326"></a>      <span class="n">buf</span> <span class="o">+=</span> <span class="s">&quot;, password=&quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">password</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-327"></a>    <span class="k">return</span> <span class="n">buf</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-328"></a>
<a name="MQTTV311.py-pyg.html-329"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-330"></a>    <span class="n">rc</span> <span class="o">=</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-331"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolName</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">ProtocolName</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-332"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">ProtocolVersion</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">ProtocolVersion</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-333"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">CleanSession</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">CleanSession</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-334"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillFlag</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-335"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">KeepAliveTimer</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">KeepAliveTimer</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-336"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">ClientIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">ClientIdentifier</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-337"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillFlag</span>
<a name="MQTTV311.py-pyg.html-338"></a>    <span class="k">if</span> <span class="n">rc</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillFlag</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-339"></a>      <span class="n">rc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">WillQoS</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillQoS</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-340"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillRETAIN</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-341"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">WillTopic</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillTopic</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-342"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">WillMessage</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">WillMessage</span>
<a name="MQTTV311.py-pyg.html-343"></a>    <span class="k">return</span> <span class="n">rc</span>
<a name="MQTTV311.py-pyg.html-344"></a>
<a name="MQTTV311.py-pyg.html-345"></a>
<a name="MQTTV311.py-pyg.html-346"></a><span class="k">class</span> <span class="nc">Connacks</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-347"></a>
<a name="MQTTV311.py-pyg.html-348"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">ReturnCode</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-349"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">CONNACK</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-350"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-351"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-352"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-353"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">returnCode</span> <span class="o">=</span> <span class="n">ReturnCode</span>
<a name="MQTTV311.py-pyg.html-354"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-355"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-356"></a>
<a name="MQTTV311.py-pyg.html-357"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-358"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="nb">bytes</span><span class="p">([</span><span class="mi">0</span><span class="p">,</span> <span class="bp">self</span><span class="o">.</span><span class="n">returnCode</span><span class="p">])</span>
<a name="MQTTV311.py-pyg.html-359"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-360"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-361"></a>
<a name="MQTTV311.py-pyg.html-362"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-363"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">4</span>
<a name="MQTTV311.py-pyg.html-364"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">CONNACK</span>
<a name="MQTTV311.py-pyg.html-365"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-366"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Connack packet is wrong length </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-367"></a>    <span class="k">assert</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;Reserved byte&quot;</span>
<a name="MQTTV311.py-pyg.html-368"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">returnCode</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-369"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-370"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-371"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-372"></a>
<a name="MQTTV311.py-pyg.html-373"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-374"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, ReturnCode=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">returnCode</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-375"></a>
<a name="MQTTV311.py-pyg.html-376"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-377"></a>    <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-378"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">returnCode</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">returnCode</span>
<a name="MQTTV311.py-pyg.html-379"></a>
<a name="MQTTV311.py-pyg.html-380"></a>
<a name="MQTTV311.py-pyg.html-381"></a><span class="k">class</span> <span class="nc">Disconnects</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-382"></a>
<a name="MQTTV311.py-pyg.html-383"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-384"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">DISCONNECT</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-385"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-386"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-387"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-388"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-389"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-390"></a>
<a name="MQTTV311.py-pyg.html-391"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-392"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-393"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">DISCONNECT</span>
<a name="MQTTV311.py-pyg.html-394"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-395"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;Disconnect packet is wrong length </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-396"></a>    <span class="n">logging</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.14.1-1] disconnect reserved bits must be 0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-397"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-398"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-399"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-400"></a>
<a name="MQTTV311.py-pyg.html-401"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-402"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-403"></a>
<a name="MQTTV311.py-pyg.html-404"></a>
<a name="MQTTV311.py-pyg.html-405"></a><span class="k">class</span> <span class="nc">Publishes</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-406"></a>
<a name="MQTTV311.py-pyg.html-407"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">TopicName</span><span class="o">=</span><span class="s">&quot;&quot;</span><span class="p">,</span> <span class="n">Payload</span><span class="o">=</span><span class="n">b</span><span class="s">&quot;&quot;</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-408"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">PUBLISH</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-409"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-410"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-411"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-412"></a>    <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-413"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">topicName</span> <span class="o">=</span> <span class="n">TopicName</span>
<a name="MQTTV311.py-pyg.html-414"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-415"></a>    <span class="c"># payload</span>
<a name="MQTTV311.py-pyg.html-416"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">Payload</span>
<a name="MQTTV311.py-pyg.html-417"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-418"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-419"></a>
<a name="MQTTV311.py-pyg.html-420"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-421"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">topicName</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-422"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-423"></a>      <span class="nb">buffer</span> <span class="o">+=</span>  <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-424"></a>    <span class="nb">buffer</span> <span class="o">+=</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span>
<a name="MQTTV311.py-pyg.html-425"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-426"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-427"></a>
<a name="MQTTV311.py-pyg.html-428"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-429"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-430"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">PUBLISH</span>
<a name="MQTTV311.py-pyg.html-431"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-432"></a>    <span class="n">packlen</span> <span class="o">=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-433"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">packlen</span>
<a name="MQTTV311.py-pyg.html-434"></a>    <span class="n">curlen</span> <span class="o">=</span> <span class="n">fhlen</span>
<a name="MQTTV311.py-pyg.html-435"></a>    <span class="k">try</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-436"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">topicName</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:],</span> <span class="n">packlen</span> <span class="o">-</span> <span class="n">curlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-437"></a>    <span class="k">except</span> <span class="ne">UnicodeDecodeError</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-438"></a>      <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.3.2-1] topic name in publish must be utf-8&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-439"></a>      <span class="k">raise</span>
<a name="MQTTV311.py-pyg.html-440"></a>    <span class="n">curlen</span> <span class="o">+=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">topicName</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-441"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-442"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-443"></a>      <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-2.3.1-1] packet indentifier must be in publish if QoS is 1 or 2&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-444"></a>      <span class="n">curlen</span> <span class="o">+=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-445"></a>      <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.3.1-1] packet indentifier must be &gt; 0&quot;</span>
<a name="MQTTV311.py-pyg.html-446"></a>    <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-447"></a>      <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-2.3.1-5] no packet indentifier in publish if QoS is 0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-448"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-449"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="n">curlen</span><span class="p">:</span><span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-450"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-451"></a>      <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-4]&quot;</span>
<a name="MQTTV311.py-pyg.html-452"></a>    <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-453"></a>
<a name="MQTTV311.py-pyg.html-454"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-455"></a>    <span class="n">rc</span> <span class="o">=</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-456"></a>    <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-457"></a>      <span class="n">rc</span> <span class="o">+=</span> <span class="s">&quot;, MsgId=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-458"></a>    <span class="n">rc</span> <span class="o">+=</span> <span class="s">&quot;, TopicName=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">topicName</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, Payload=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-459"></a>    <span class="k">return</span> <span class="n">rc</span>
<a name="MQTTV311.py-pyg.html-460"></a>
<a name="MQTTV311.py-pyg.html-461"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-462"></a>    <span class="n">rc</span> <span class="o">=</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-463"></a>         <span class="bp">self</span><span class="o">.</span><span class="n">topicName</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">topicName</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-464"></a>         <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">data</span>
<a name="MQTTV311.py-pyg.html-465"></a>    <span class="k">if</span> <span class="n">rc</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-466"></a>      <span class="n">rc</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span>
<a name="MQTTV311.py-pyg.html-467"></a>    <span class="k">return</span> <span class="n">rc</span>
<a name="MQTTV311.py-pyg.html-468"></a>
<a name="MQTTV311.py-pyg.html-469"></a>
<a name="MQTTV311.py-pyg.html-470"></a><span class="k">class</span> <span class="nc">Pubacks</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-471"></a>
<a name="MQTTV311.py-pyg.html-472"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-473"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">PUBACK</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-474"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-475"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-476"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-477"></a>    <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-478"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-479"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-480"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-481"></a>
<a name="MQTTV311.py-pyg.html-482"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-483"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-484"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-485"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-486"></a>
<a name="MQTTV311.py-pyg.html-487"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-488"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-489"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">PUBACK</span>
<a name="MQTTV311.py-pyg.html-490"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-491"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Puback packet is wrong length </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-492"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-493"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-494"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-495"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-496"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-497"></a>    <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-498"></a>
<a name="MQTTV311.py-pyg.html-499"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-500"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, MsgId &quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-501"></a>
<a name="MQTTV311.py-pyg.html-502"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-503"></a>    <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-504"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span>
<a name="MQTTV311.py-pyg.html-505"></a>
<a name="MQTTV311.py-pyg.html-506"></a>
<a name="MQTTV311.py-pyg.html-507"></a><span class="k">class</span> <span class="nc">Pubrecs</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-508"></a>
<a name="MQTTV311.py-pyg.html-509"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-510"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">PUBREC</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-511"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-512"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-513"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-514"></a>    <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-515"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-516"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-517"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-518"></a>
<a name="MQTTV311.py-pyg.html-519"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-520"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-521"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-522"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-523"></a>
<a name="MQTTV311.py-pyg.html-524"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-525"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-526"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">PUBREC</span>
<a name="MQTTV311.py-pyg.html-527"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-528"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Pubrec packet is wrong length </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-529"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-530"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-531"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-532"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-533"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-534"></a>    <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-535"></a>
<a name="MQTTV311.py-pyg.html-536"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-537"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, MsgId=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-538"></a>
<a name="MQTTV311.py-pyg.html-539"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-540"></a>    <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-541"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span>
<a name="MQTTV311.py-pyg.html-542"></a>
<a name="MQTTV311.py-pyg.html-543"></a>
<a name="MQTTV311.py-pyg.html-544"></a><span class="k">class</span> <span class="nc">Pubrels</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-545"></a>
<a name="MQTTV311.py-pyg.html-546"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-547"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">PUBREL</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-548"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-549"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-550"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-551"></a>    <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-552"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-553"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-554"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-555"></a>
<a name="MQTTV311.py-pyg.html-556"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-557"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-558"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-559"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-560"></a>
<a name="MQTTV311.py-pyg.html-561"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-562"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-563"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">PUBREL</span>
<a name="MQTTV311.py-pyg.html-564"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-565"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Pubrel packet is wrong length </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-566"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-567"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-568"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1] DUP should be False in PUBREL&quot;</span>
<a name="MQTTV311.py-pyg.html-569"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1] QoS should be 1 in PUBREL&quot;</span>
<a name="MQTTV311.py-pyg.html-570"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1] RETAIN should be False in PUBREL&quot;</span>
<a name="MQTTV311.py-pyg.html-571"></a>    <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3.6.1-1] bits in fixed header for pubrel are ok&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-572"></a>    <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-573"></a>
<a name="MQTTV311.py-pyg.html-574"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-575"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, MsgId=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-576"></a>
<a name="MQTTV311.py-pyg.html-577"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-578"></a>    <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-579"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span>
<a name="MQTTV311.py-pyg.html-580"></a>
<a name="MQTTV311.py-pyg.html-581"></a>
<a name="MQTTV311.py-pyg.html-582"></a><span class="k">class</span> <span class="nc">Pubcomps</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-583"></a>
<a name="MQTTV311.py-pyg.html-584"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-585"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">PUBCOMP</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-586"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-587"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-588"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-589"></a>    <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-590"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-591"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-592"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-593"></a>
<a name="MQTTV311.py-pyg.html-594"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-595"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-596"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-597"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-598"></a>
<a name="MQTTV311.py-pyg.html-599"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-600"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-601"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">PUBCOMP</span>
<a name="MQTTV311.py-pyg.html-602"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-603"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-604"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">2</span><span class="p">,</span> <span class="s">&quot;Pubcomp packet is wrong length </span><span class="si">%d</span><span class="s">&quot;</span> <span class="o">%</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-605"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-606"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1] DUP should be False in Pubcomp&quot;</span>
<a name="MQTTV311.py-pyg.html-607"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1] QoS should be 0 in Pubcomp&quot;</span>
<a name="MQTTV311.py-pyg.html-608"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1] Retain should be false in Pubcomp&quot;</span>
<a name="MQTTV311.py-pyg.html-609"></a>    <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-610"></a>
<a name="MQTTV311.py-pyg.html-611"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-612"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, MsgId=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-613"></a>
<a name="MQTTV311.py-pyg.html-614"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-615"></a>    <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-616"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span>
<a name="MQTTV311.py-pyg.html-617"></a>
<a name="MQTTV311.py-pyg.html-618"></a>
<a name="MQTTV311.py-pyg.html-619"></a><span class="k">class</span> <span class="nc">Subscribes</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-620"></a>
<a name="MQTTV311.py-pyg.html-621"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Data</span><span class="o">=</span><span class="p">[]):</span>
<a name="MQTTV311.py-pyg.html-622"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">SUBSCRIBE</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-623"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-624"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-625"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-626"></a>    <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-627"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-628"></a>    <span class="c"># payload - list of topic, qos pairs</span>
<a name="MQTTV311.py-pyg.html-629"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">Data</span><span class="p">[:]</span>
<a name="MQTTV311.py-pyg.html-630"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-631"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-632"></a>
<a name="MQTTV311.py-pyg.html-633"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-634"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-635"></a>    <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-636"></a>      <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="n">d</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span> <span class="o">+</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">d</span><span class="p">[</span><span class="mi">1</span><span class="p">]])</span>
<a name="MQTTV311.py-pyg.html-637"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-638"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-639"></a>
<a name="MQTTV311.py-pyg.html-640"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-641"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-642"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">SUBSCRIBE</span>
<a name="MQTTV311.py-pyg.html-643"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-644"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-645"></a>    <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-2.3.1-1] packet indentifier must be in subscribe&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-646"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-647"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.3.1-1] packet indentifier must be &gt; 0&quot;</span>
<a name="MQTTV311.py-pyg.html-648"></a>    <span class="n">leftlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">-</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-649"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">[]</span>
<a name="MQTTV311.py-pyg.html-650"></a>    <span class="k">while</span> <span class="n">leftlen</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-651"></a>      <span class="n">topic</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="o">-</span><span class="n">leftlen</span><span class="p">:],</span> <span class="n">leftlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-652"></a>      <span class="n">leftlen</span> <span class="o">-=</span> <span class="nb">len</span><span class="p">(</span><span class="n">topic</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-653"></a>      <span class="n">qos</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="o">-</span><span class="n">leftlen</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-654"></a>      <span class="k">assert</span> <span class="n">qos</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">],</span> <span class="s">&quot;[MQTT-3.8.3-2] reserved bits must be zero&quot;</span>
<a name="MQTTV311.py-pyg.html-655"></a>      <span class="n">leftlen</span> <span class="o">-=</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-656"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">append</span><span class="p">((</span><span class="n">topic</span><span class="p">,</span> <span class="n">qos</span><span class="p">))</span>
<a name="MQTTV311.py-pyg.html-657"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-3.8.3-1] at least one topic, qos pair must be in subscribe&quot;</span>
<a name="MQTTV311.py-pyg.html-658"></a>    <span class="k">assert</span> <span class="n">leftlen</span> <span class="o">==</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-659"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-660"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-661"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-662"></a>    <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-663"></a>
<a name="MQTTV311.py-pyg.html-664"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-665"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, MsgId=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span><span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-666"></a>           <span class="s">&quot;, Data=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-667"></a>
<a name="MQTTV311.py-pyg.html-668"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-669"></a>    <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-670"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-671"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">data</span>
<a name="MQTTV311.py-pyg.html-672"></a>
<a name="MQTTV311.py-pyg.html-673"></a>
<a name="MQTTV311.py-pyg.html-674"></a><span class="k">class</span> <span class="nc">Subacks</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-675"></a>
<a name="MQTTV311.py-pyg.html-676"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Data</span><span class="o">=</span><span class="p">[]):</span>
<a name="MQTTV311.py-pyg.html-677"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">SUBACK</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-678"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-679"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-680"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-681"></a>    <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-682"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-683"></a>    <span class="c"># payload - list of qos</span>
<a name="MQTTV311.py-pyg.html-684"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">Data</span><span class="p">[:]</span>
<a name="MQTTV311.py-pyg.html-685"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-686"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-687"></a>
<a name="MQTTV311.py-pyg.html-688"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-689"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-690"></a>    <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-691"></a>      <span class="nb">buffer</span> <span class="o">+=</span> <span class="nb">bytes</span><span class="p">([</span><span class="n">d</span><span class="p">])</span>
<a name="MQTTV311.py-pyg.html-692"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-693"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-694"></a>
<a name="MQTTV311.py-pyg.html-695"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-696"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-697"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">SUBACK</span>
<a name="MQTTV311.py-pyg.html-698"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-699"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-700"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-701"></a>    <span class="n">leftlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">-</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-702"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">[]</span>
<a name="MQTTV311.py-pyg.html-703"></a>    <span class="k">while</span> <span class="n">leftlen</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-704"></a>      <span class="n">qos</span> <span class="o">=</span> <span class="nb">buffer</span><span class="p">[</span><span class="o">-</span><span class="n">leftlen</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-705"></a>      <span class="k">assert</span> <span class="n">qos</span> <span class="ow">in</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mh">0x80</span><span class="p">],</span> <span class="s">&quot;[MQTT-3.9.3-2] return code in QoS must be 0, 1, 2 or 0x80&quot;</span>
<a name="MQTTV311.py-pyg.html-706"></a>      <span class="n">leftlen</span> <span class="o">-=</span> <span class="mi">1</span>
<a name="MQTTV311.py-pyg.html-707"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">qos</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-708"></a>    <span class="k">assert</span> <span class="n">leftlen</span> <span class="o">==</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-709"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1] DUP should be false in suback&quot;</span>
<a name="MQTTV311.py-pyg.html-710"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1] QoS should be 0 in suback&quot;</span>
<a name="MQTTV311.py-pyg.html-711"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1] Retain should be false in suback&quot;</span>
<a name="MQTTV311.py-pyg.html-712"></a>    <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-713"></a>
<a name="MQTTV311.py-pyg.html-714"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-715"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, MsgId=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span><span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-716"></a>           <span class="s">&quot;, Data=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-717"></a>
<a name="MQTTV311.py-pyg.html-718"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-719"></a>    <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-720"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-721"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">data</span>
<a name="MQTTV311.py-pyg.html-722"></a>
<a name="MQTTV311.py-pyg.html-723"></a>
<a name="MQTTV311.py-pyg.html-724"></a><span class="k">class</span> <span class="nc">Unsubscribes</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-725"></a>
<a name="MQTTV311.py-pyg.html-726"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Data</span><span class="o">=</span><span class="p">[]):</span>
<a name="MQTTV311.py-pyg.html-727"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">UNSUBSCRIBE</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-728"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-729"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-730"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-731"></a>    <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-732"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-733"></a>    <span class="c"># payload - list of topics</span>
<a name="MQTTV311.py-pyg.html-734"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="n">Data</span><span class="p">[:]</span>
<a name="MQTTV311.py-pyg.html-735"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-736"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-737"></a>
<a name="MQTTV311.py-pyg.html-738"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-739"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-740"></a>    <span class="k">for</span> <span class="n">d</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-741"></a>      <span class="nb">buffer</span> <span class="o">+=</span> <span class="n">writeUTF</span><span class="p">(</span><span class="n">d</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-742"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-743"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-744"></a>
<a name="MQTTV311.py-pyg.html-745"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-746"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-747"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">UNSUBSCRIBE</span>
<a name="MQTTV311.py-pyg.html-748"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-749"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-750"></a>    <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-2.3.1-1] packet indentifier must be in unsubscribe&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-751"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-752"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.3.1-1] packet indentifier must be &gt; 0&quot;</span>
<a name="MQTTV311.py-pyg.html-753"></a>    <span class="n">leftlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">-</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-754"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">=</span> <span class="p">[]</span>
<a name="MQTTV311.py-pyg.html-755"></a>    <span class="k">while</span> <span class="n">leftlen</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-756"></a>      <span class="n">topic</span> <span class="o">=</span> <span class="n">readUTF</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="o">-</span><span class="n">leftlen</span><span class="p">:],</span> <span class="n">leftlen</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-757"></a>      <span class="n">leftlen</span> <span class="o">-=</span> <span class="nb">len</span><span class="p">(</span><span class="n">topic</span><span class="p">)</span> <span class="o">+</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-758"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">topic</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-759"></a>    <span class="k">assert</span> <span class="n">leftlen</span> <span class="o">==</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-760"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-761"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">1</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-762"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-763"></a>    <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="s">&quot;[MQTT-3-10.1-1] fixed header bits arebe 0,0,1,0&quot;</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-764"></a>    <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-765"></a>
<a name="MQTTV311.py-pyg.html-766"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-767"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, MsgId=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span><span class="o">+</span>\
<a name="MQTTV311.py-pyg.html-768"></a>           <span class="s">&quot;, Data=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">data</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-769"></a>
<a name="MQTTV311.py-pyg.html-770"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-771"></a>    <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-772"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-773"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">data</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">data</span>
<a name="MQTTV311.py-pyg.html-774"></a>
<a name="MQTTV311.py-pyg.html-775"></a>
<a name="MQTTV311.py-pyg.html-776"></a><span class="k">class</span> <span class="nc">Unsubacks</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-777"></a>
<a name="MQTTV311.py-pyg.html-778"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">MsgId</span><span class="o">=</span><span class="mi">0</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-779"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">UNSUBACK</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-780"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-781"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-782"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-783"></a>    <span class="c"># variable header</span>
<a name="MQTTV311.py-pyg.html-784"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">MsgId</span>
<a name="MQTTV311.py-pyg.html-785"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-786"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-787"></a>
<a name="MQTTV311.py-pyg.html-788"></a>  <span class="k">def</span> <span class="nf">pack</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-789"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="n">writeInt16</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-790"></a>    <span class="nb">buffer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">pack</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">))</span> <span class="o">+</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-791"></a>    <span class="k">return</span> <span class="nb">buffer</span>
<a name="MQTTV311.py-pyg.html-792"></a>
<a name="MQTTV311.py-pyg.html-793"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-794"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-795"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">UNSUBACK</span>
<a name="MQTTV311.py-pyg.html-796"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-797"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-798"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-799"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.3.1-1] packet indentifier must be &gt; 0&quot;</span>
<a name="MQTTV311.py-pyg.html-800"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">=</span> <span class="n">readInt16</span><span class="p">(</span><span class="nb">buffer</span><span class="p">[</span><span class="n">fhlen</span><span class="p">:])</span>
<a name="MQTTV311.py-pyg.html-801"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-802"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-803"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-804"></a>    <span class="k">return</span> <span class="n">fhlen</span> <span class="o">+</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span>
<a name="MQTTV311.py-pyg.html-805"></a>
<a name="MQTTV311.py-pyg.html-806"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-807"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;, MsgId=&quot;</span><span class="o">+</span><span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-808"></a>
<a name="MQTTV311.py-pyg.html-809"></a>  <span class="k">def</span> <span class="nf">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-810"></a>    <span class="k">return</span> <span class="n">Packets</span><span class="o">.</span><span class="n">__eq__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">packet</span><span class="p">)</span> <span class="ow">and</span> \
<a name="MQTTV311.py-pyg.html-811"></a>           <span class="bp">self</span><span class="o">.</span><span class="n">messageIdentifier</span> <span class="o">==</span> <span class="n">packet</span><span class="o">.</span><span class="n">messageIdentifier</span>
<a name="MQTTV311.py-pyg.html-812"></a>
<a name="MQTTV311.py-pyg.html-813"></a>
<a name="MQTTV311.py-pyg.html-814"></a><span class="k">class</span> <span class="nc">Pingreqs</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-815"></a>
<a name="MQTTV311.py-pyg.html-816"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-817"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">PINGREQ</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-818"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-819"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-820"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-821"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-822"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-823"></a>
<a name="MQTTV311.py-pyg.html-824"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-825"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-826"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">PINGREQ</span>
<a name="MQTTV311.py-pyg.html-827"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-828"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-829"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-830"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-831"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-832"></a>    <span class="k">return</span> <span class="n">fhlen</span>
<a name="MQTTV311.py-pyg.html-833"></a>
<a name="MQTTV311.py-pyg.html-834"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-835"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-836"></a>
<a name="MQTTV311.py-pyg.html-837"></a>
<a name="MQTTV311.py-pyg.html-838"></a><span class="k">class</span> <span class="nc">Pingresps</span><span class="p">(</span><span class="n">Packets</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-839"></a>
<a name="MQTTV311.py-pyg.html-840"></a>  <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">DUP</span><span class="o">=</span><span class="bp">False</span><span class="p">,</span> <span class="n">QoS</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">Retain</span><span class="o">=</span><span class="bp">False</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-841"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span> <span class="o">=</span> <span class="n">FixedHeaders</span><span class="p">(</span><span class="n">PINGRESP</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-842"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">=</span> <span class="n">DUP</span>
<a name="MQTTV311.py-pyg.html-843"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">=</span> <span class="n">QoS</span>
<a name="MQTTV311.py-pyg.html-844"></a>    <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">Retain</span> <span class="o">=</span> <span class="n">Retain</span>
<a name="MQTTV311.py-pyg.html-845"></a>    <span class="k">if</span> <span class="nb">buffer</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-846"></a>      <span class="bp">self</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-847"></a>
<a name="MQTTV311.py-pyg.html-848"></a>  <span class="k">def</span> <span class="nf">unpack</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-849"></a>    <span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="mi">2</span>
<a name="MQTTV311.py-pyg.html-850"></a>    <span class="k">assert</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">==</span> <span class="n">PINGRESP</span>
<a name="MQTTV311.py-pyg.html-851"></a>    <span class="n">fhlen</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-852"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">remainingLength</span> <span class="o">==</span> <span class="mi">0</span>
<a name="MQTTV311.py-pyg.html-853"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">DUP</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-854"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">QoS</span> <span class="o">==</span> <span class="mi">0</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-855"></a>    <span class="k">assert</span> <span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="o">.</span><span class="n">RETAIN</span> <span class="o">==</span> <span class="bp">False</span><span class="p">,</span> <span class="s">&quot;[MQTT-2.1.2-1]&quot;</span>
<a name="MQTTV311.py-pyg.html-856"></a>    <span class="k">return</span> <span class="n">fhlen</span>
<a name="MQTTV311.py-pyg.html-857"></a>
<a name="MQTTV311.py-pyg.html-858"></a>  <span class="k">def</span> <span class="nf">__repr__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-859"></a>    <span class="k">return</span> <span class="nb">repr</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">fh</span><span class="p">)</span><span class="o">+</span><span class="s">&quot;)&quot;</span>
<a name="MQTTV311.py-pyg.html-860"></a>
<a name="MQTTV311.py-pyg.html-861"></a><span class="n">classes</span> <span class="o">=</span> <span class="p">[</span><span class="bp">None</span><span class="p">,</span> <span class="n">Connects</span><span class="p">,</span> <span class="n">Connacks</span><span class="p">,</span> <span class="n">Publishes</span><span class="p">,</span> <span class="n">Pubacks</span><span class="p">,</span> <span class="n">Pubrecs</span><span class="p">,</span>
<a name="MQTTV311.py-pyg.html-862"></a>           <span class="n">Pubrels</span><span class="p">,</span> <span class="n">Pubcomps</span><span class="p">,</span> <span class="n">Subscribes</span><span class="p">,</span> <span class="n">Subacks</span><span class="p">,</span> <span class="n">Unsubscribes</span><span class="p">,</span>
<a name="MQTTV311.py-pyg.html-863"></a>           <span class="n">Unsubacks</span><span class="p">,</span> <span class="n">Pingreqs</span><span class="p">,</span> <span class="n">Pingresps</span><span class="p">,</span> <span class="n">Disconnects</span><span class="p">]</span>
<a name="MQTTV311.py-pyg.html-864"></a>
<a name="MQTTV311.py-pyg.html-865"></a><span class="k">def</span> <span class="nf">unpackPacket</span><span class="p">(</span><span class="nb">buffer</span><span class="p">):</span>
<a name="MQTTV311.py-pyg.html-866"></a>  <span class="k">if</span> <span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span> <span class="o">!=</span> <span class="bp">None</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-867"></a>    <span class="n">packet</span> <span class="o">=</span> <span class="n">classes</span><span class="p">[</span><span class="n">MessageType</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)]()</span>
<a name="MQTTV311.py-pyg.html-868"></a>    <span class="n">packet</span><span class="o">.</span><span class="n">unpack</span><span class="p">(</span><span class="nb">buffer</span><span class="p">)</span>
<a name="MQTTV311.py-pyg.html-869"></a>  <span class="k">else</span><span class="p">:</span>
<a name="MQTTV311.py-pyg.html-870"></a>    <span class="n">packet</span> <span class="o">=</span> <span class="bp">None</span>
<a name="MQTTV311.py-pyg.html-871"></a>  <span class="k">return</span> <span class="n">packet</span>
</pre></div>

</pre>

    </body>
</html>